package com.cwj.juc;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 生产者-消费者模型
 * @author: Chenwujie
 * @date: 2021-05-08 15:12
 */
public class ProducerConsumerModel {
    private LinkedBlockingQueue<Integer> queue;

    public ProducerConsumerModel(int n) {
        this.queue = new LinkedBlockingQueue<>(n);
    }

    public static void main(String[] args) {


        LinkedBlockingQueue<Runnable> myTasks = new LinkedBlockingQueue<>(10);
        LinkedBlockingQueue<Runnable> myTasks2 = new LinkedBlockingQueue<>(10);
        ThreadPoolExecutor p_executor = new ThreadPoolExecutor(3, 3, 10, TimeUnit.SECONDS, myTasks);
        ThreadPoolExecutor c_executor = new ThreadPoolExecutor(3, 3, 10, TimeUnit.SECONDS, myTasks2);

        ProducerConsumerModel demo01 = new ProducerConsumerModel(10);
        MyTask myTask = new MyTask(demo01);
        MyTask02 myTask02 = new MyTask02(demo01);
        for (int i=0;i<20;i++){
            p_executor.execute(myTask);
            c_executor.execute(myTask02);
        }
    }

    public void add(int n) throws InterruptedException {
        queue.put(n);
        System.out.println(Thread.currentThread().getName()+"生产一个商品：" + n + "，目前总数：" + queue.size());
    }

    public void remove() throws InterruptedException {
        Integer n = queue.take();
        System.out.println(Thread.currentThread().getName()+"消费一个商品：" + n + "，目前总数：" + queue.size());
    }

    static class MyTask implements Runnable{
        private final ProducerConsumerModel demo01;
        @Override
        public void run() {
            try {
                demo01.add(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public MyTask(ProducerConsumerModel demo01) {
            this.demo01 = demo01;
        }
    }

    static class MyTask02 implements Runnable{
        private final ProducerConsumerModel demo01;
        @Override
        public void run() {
            try {
                demo01.remove();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public MyTask02(ProducerConsumerModel demo01) {
            this.demo01 = demo01;
        }
    }
}
